<?php declare(strict_types=1);

namespace App\Services\PengYiPeng;


use App\Api\Controllers\Merchant\OrderController;
use App\Api\Controllers\Merchant\PayBaseController;
use App\Models\Device;
use App\Models\DeviceServiceProviders;
use App\Models\Order;
use App\Models\RefundOrder;
use App\Models\Store;
use App\Models\StoreAliyunAuth;
use App\Services\Count\MerchantBillCountService;
use App\Utils\AliYun\request\AlipayCommerceIotDeviceRecordsSetRequest;
use App\Utils\AliYun\request\AlipayMerchantOrderExternalPaychannelSyncRequest;
use App\Utils\AliYun\request\AlipayOpenAuthTokenAppRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ThridLiteService
{
//    const GatewayUrl = "https://openapi.alipay.com/gateway.do";

    /**这个是皖付通网页移动应用参数
     * const AppID = "2021004190649336";
     *
     * const RsaPrivateKKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCbKQslVAQUVzH2KCSFlKumh903iwdupSBbW7J0gFBILIbUCTyFhNXGgXlOSu0Rw/XOHWy66NEHSyV0ViHLwh4qgdygpH7Avi2bDVfyKeBPWLXMr1b1cX1ALbgU15E92Sw95zCKTFCseFgomLMYv0Z1aTLTJJ/Aly4RPyHAWOcJL262hIwkYBNZhrcWmIuBRXSjOMKxM6sNsUfe+6+29pnZzGUhJSVS0+LLLgwMu0CUod6Kd/0zxj6NphbylKc2wxIAhM+co087Oxqk9aTdNKYB2SScnYweH5efXB1JOT8hXI8bU3wlr3qGepNO/WZMnW5WgV5WqfYh0balSjKPH6APAgMBAAECggEAN07FE1REc/+05nreseMR4LWzbDYZux4PT6F7Fj4a3+9HTFPSiAGWtkC2verFYLzKZONmO6X7xK7LthFx0JDscdiCjZy1Nf1Ugl2aSM8WjxIfE8w4ohsHO5ZQdNV2h2Zfd91uFw4m/6OSQT5VMPAVrIqIPG1kqKD7IdiwLkFCcaoxmvFyb+r9kFkZupEKXsDov+D22W0D8qqANlXpbL1bVnWQHrPdMxShUXaerKCtVZ2EGTk+qf11CgcJ0+ud52vOlsUBJWro5+5ICUstMOCHwWw3OVhOstJSpizkGNkBl5JrdPmeeA54jG2EF1lHB1x89VYrZzgj+FoueU4/v7VIyQKBgQDMN0eZ7sGjmj3AzcxHLsFNIrnmWY5jIV4viABl6k0DJhOUkIpXSElld4LYZ0CW7QwTE7LOdXyW7w12gXxelbxaPA4IyPpXI0ncP5CSMHbxzJGZcc8OzfWN5hl2k/wUtLcep3bkXiSHvXD+n0Ma73wBqLklKpEZvycF2dHvHJSMIwKBgQDCgU8DLhjCn0Skwdu4Dn6BVJ8BOWQQLlrug2JBoNeRxdOMBFY//NKoTgadkWN0AofkRAdn2FtDv/8k/AgwDH+wGeZ/s7GUMrvSXIyNBm2MCPbAPmT7MPcetCA6T1tzNDicWQYOA3mgnry2cJ0yE1/n8PS3qUT0nr0+wYiUeX2VJQKBgQCEtxw6RrbjOtcNGPG8BP+swHet4t+tPr82Bp2zngxEkpdBAppVVO4WGhAX0Sphq1Ygg7m9gQ7iDCNks4v+8DLDNaotPWer/4v9rfWnfAWg6MBqx1K4HVOKz1IXBN9bGYK0UkLq8N+us4fegeQbei3N6jfAlqRL5jVXERLk4V8MnwKBgQCkdVtOcAqFfM84k6VpEfBLADbVfSYrPFasdzB8FzhOTDublwsqXWXs4tRbJFQ4Ae/OxOqSFnDMbymXpvZxUhAg4TVw4ooSqXb/3jsE/ttfXTDtyZPuhC9eqaTaSMElPpFjOS6SaMPNWIpto/h2H8WmwqjYJepk/1c6Gb+W8saJdQKBgHUeYt+f8Jrg9fiTtnkvedWMhg8zsUtN4dCQkAw37n+kWOpw6V9H2UoCjB+TmbMQZKTyLeqxkXPOGDmdWNJSUxCLMqBijhkxZvvR8eNVNuVL1IAS0tQeEsgKrQEtIDoUGoC/vrY4R8pb3uVmkBArgPbSG3AHjlxNBRJGxU9gISH2";
     *
     *
     * const AlipayRasPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArq696YzJWydjfUPOtCJqAedMGVK1t3DbMRzJtiDeZNReQWWipR+Yk8kIDn5+s6NiTtvkPgIV/33WNWIgXxw+3qdC01mQJchdADaTjEA1JcJnw7O5UVmSX5BnRUQj9IIKccFNvXBHOM7Y97zc8e81hZuVWXTCO+drj1vW2NMAjXRi+n+nusS0JGKzyB7fjok0mYUP1BJhJ0PrDa/sfplJINLd6IkDqwse9ktmTUxzEb13SlSpvMNVMf6ASNAkc5h/nygFK7wgEe9R7kGe57ybGM+pWJXKkZp0nAUvtFRihAZi0DE3LHUbkN0hiaKUqRRIy7kUePzIKJ0LYT+uGdc/rQIDAQAB";
     *
     *
     * const ApiVersion = "1.0";
     * const SignType = "RSA2";
     * const PostCharset = "utf-8";//"GBK"; //GBK
     * const Format = "json"; //GBK
     * const AESKEY = "6N9IZvze0+bF1hJgOtZT5g==";
     * const SupplierId = "202008061702346558";
     *
     * const WFTPID = "2088441062310612";
     */
//"sn" => "LDN7HDQM024100905169",
//"supplier_id" => "202008061702346558",
//"biztid" => "01010QV0hq5XHtCpzQmGlOrPljB95Lw7XX9xmA9EbKcrewlxNOlaj0U",
    public $aop; //AopClient

    //接口内容加密方式
    //AES 6N9IZvze0+bF1hJgOtZT5g==

    public function __construct()
    {
        $aop = new \App\Utils\AliYun\AopClient();
        /*
            $aop->gatewayUrl = self::GatewayUrl;
            $aop->appId = self::AppID;
            $aop->rsaPrivateKey = self::RsaPrivateKKey;
            $aop->alipayrsaPublicKey = self::AlipayRasPublicKey;
            $aop->apiVersion = self::ApiVersion;
            $aop->signType = self::SignType;
            $aop->postCharset = self::PostCharset;
            $aop->format = self::Format;
            $aop->encryptKey = self::AESKEY;
            $this->aop = $aop;
        */

        $aop->gatewayUrl = config("lite.gatewayUrl");
        $aop->appId = config("lite.threePartyApplication.appId");
        $aop->rsaPrivateKey = config("lite.threePartyApplication.rsaPrivateKey");
        $aop->alipayrsaPublicKey = config("lite.threePartyApplication.alipayrsaPublicKey");
        $aop->apiVersion = config("lite.threePartyApplication.apiVersion");
        $aop->signType = config("lite.threePartyApplication.signType");
        $aop->postCharset = config("lite.threePartyApplication.postCharset");
        $aop->format = config("lite.threePartyApplication.format");
        $aop->encryptKey = config("lite.threePartyApplication.encryptKey");
        $this->aop = $aop;


    }

//[2024-10-24 11:14:58] local.INFO: 请求参数：2024-10-24 11:14:58 {"data":{"app_id":"2021004167603274","source":"alipay_app_auth","state":"STORE_ID_VALUE","app_auth_code":"P9e22493d30dc49aeb3879e53d818f64"}}
    public function deviceSet(string $scene, string $action, array $data, ?string $token = null): array
    {
        //参数校验
        if (!in_array($scene, [
            "IOT_DEVICE_RECORDS_G3_INDIRECT",
            "IOT_DEVICE_RECORDS_G3_DIRECT",
            "IOT_DEVICE_RECORDS_DELETE",
            "IOT_DEVICE_RECORDS_QUERY",
            "IOT_DEVICE_RECORDS_G2"
        ])) {
            throw new \Exception("参数异常");
        }
        switch ($action) {
            case "QUERY":
            case "DELETE":
                $scene_params = "DEFAULT";
                break;
            case "BIND":
                $scene_params = "CREATE";
                break;
            case "UPGRADE" :
                $scene_params = "G2TOG3_UPDATE";
                break;
            default:
                throw new \Exception("参数异常");

        }
        switch ($scene) {
            case "IOT_DEVICE_RECORDS_G2":
            case  "IOT_DEVICE_RECORDS_DELETE":
                $device_record_files = [
                    [
                        "records_type" => "RECORDS_TYPE_SMID",
                        "records_value" => $data["RECORDS_TYPE_SMID"],
                    ],
//                    [
//                        "records_type" => "RECORDS_TYPE_PID",
//                        "records_value" => self::WFTPID,
//                    ]
                ];
//                $aliyunStoreId = $this->getAliYunStoreId($data["sn"], $data["store_id"]);
                if (!empty($data["external_shop_id"])) {
                    $external_shop_id = $data["external_shop_id"];
                } else {
                    $external_shop_id = substr($data["sn"], 0, 4) . time();
                }
                $ext_params = [
                    "payment_type" => "SPI", //支付类型
                    "source" => config("lite.threePartyApplication.pid"),   //???   进件服务商 PID
                    "spi_app_id" => config("lite.spiApplication.appId"), //支付调用的SPI应用的APPID   表示服务商在开放平台注册的 SPI 服务应用的 app_id，用于标识服务商身份
                    "terminal_bind_info" => json_encode(["device_no" => $data["sn"] ?? "", "store_id" => $data["store_id"], "store_name" => $data["store_name"], "user_id" => $data["user_id"]]),  //服务商内部唯一标识商家、商家门店等字段信息；可作为服务商自主对接的扩展字段使用
                    "external_shop_id" => $external_shop_id,
                    "shop_name" => $data["store_name"] ?? "",
                    "external_id" => $external_shop_id,
                ];
                break;
        }

        try {
            Log::channel("iot")->error("bindSetStart_" . date("Y-m-d H:i:s", time()), ["data" => $data]);
            //设备绑定查询
            $request = new AlipayCommerceIotDeviceRecordsSetRequest();
//            $request->setNeedEncrypt(true);
//$request->setNotifyUrl("https://test-pay.zgjindoufu.com/api/v2/Notify/AliyunNotify/notify");

#设备档案管理场景  scene_code
//IOT_DEVICE_RECORDS_G3_INDIRECT(间连三绑定)
//IOT_DEVICE_RECORDS_G3_DIRECT(直连三绑定)
//IOT_DEVICE_RECORDS_DELETE(解绑)
//IOT_DEVICE_RECORDS_QUERY（绑定查询）
//IOT_DEVICE_RECORDS_G2(可用绑定)
#scene_params
//CREATE（间连三绑定、可用绑定、直连三绑定时传）
//DEFAULT（解绑、绑定查询时传）
//G2TOG3_UPDATE（可用绑定升级为间联三绑定时传）
//未bind NOT_MATCH_DEVICE_OWNER
//bind-success DEVICE_RECORDS_EXIST
            $bizData = [
                "sn" => $data["sn"] ?? "",
                "supplier_id" => config("lite.supplierId"),
                "scene_code" => $scene, //bind查询
                "scene_params" => $scene_params, //创建
            ];

            if (in_array($action, ["BIND", "DELETE"])) {
                $tmp = [
                    "device_record_files" => $device_record_files,
                    "ext_params" => $ext_params
                ];
                $bizData = array_merge($bizData, $tmp);
            }
#请求参数
            /**
             * sign=***&format=json&version=1.0&app_id=2019080865999999&sign_type=RSA2&charset=utf-8&alipay_sdk=alipay-sdk-java-4.39.218.ALL&biz_content={"scene_code":"IOT_DEVICE_RECORDS_QUERY","scene_params":"DEFAULT","sn":"LDN7HDQM02492600225","supplier_id":"202008061702346558"}&method=alipay.commerce.iot.device.records.set&timestamp=2024-10-04 22:32:44
             */
            $request->setBizContent(json_encode($bizData));
//            "sn" => $data["sn"] ?? "",
//                "supplier_id" => $data["supplier_id"],
//                "scene_code" => "IOT_DEVICE_RECORDS_QUERY", //bind查询
//                "scene_params" => "DEFAULT", //创建
//            $request->setBizContent("{" .
//                "  \"scene_code\":\"IOT_DEVICE_RECORDS_QUERY\"," .
//                "  \"supplier_id\":\"202008061702346558\"," .
//                "  \"scene_params\":\"DEFAULT\"," .
//                "  \"sn\":\"LDN7HDQM024100905169\"" .
//                "}");

            //P6ef1235cb88645dd86d82d4a83e6264 这个是code ，需要调用获取token令牌
//            $appInfoAuthToken = "202410BB8af8d8c13cc348cd9e882c0dba0c7X64";
//            if (empty($appInfoAuthToken)) {
//                //获取永久token
//                //open_app_auth_notify
//                //alipay.open.auth.token.app
//                $tokenRequest = new AlipayOpenAuthTokenAppRequest();
//                $tokenRequest->setNeedEncrypt(true);
//                $tokenRequest->setBizContent(json_encode([
//                    "grant_type" => "authorization_code",
//                    "code" => "P785f34b2a41a4ab6bf541c6afb5c564",
//                ], JSON_UNESCAPED_UNICODE));
//                $tokenResult = $this->aop->execute($tokenRequest);
//                dd($tokenResult);
//            }
            $result = $this->aop->execute($request, null, $token);
            Log::channel("iot")->error("bindSetResult_" . date("Y-m-d H:i:s", time()), ["result" => json_decode(json_encode($result), true)]);
            $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
            $resultCode = $result->$responseNode->code;
            if (!empty($resultCode) && $resultCode == 10000) {
                return [true, $result->$responseNode];
            } else {
//        {#5005
//            +"msg": "Business Failed"
//        +"code": "40004"
//        +"sub_msg": "设备档案已存在"
//        +"sub_code": "DEVICE_RECORDS_EXIST"
//}
//                if ($result["code"] == "40004" && $result["sub_code"] == "DEVICE_RECORDS_EXIST") {
//                    $device->status = 1;
//                    $device->save();
//                }
                if (!empty($resultCode) && $resultCode == 40004 && $result->$responseNode->sub_code == "DEVICE_RECORDS_EXIST") {
                    return [true, $result->$responseNode];
                }
                return [false, $result->$responseNode];
            }
        } catch (\Exception $e) {
            $msg = $e->getMessage() . "|" . $e->getFile() . "|" . $e->getLine();
            Log::channel("iot")->error("bindSetError_" . date("Y-m-d H:i:s", time()), ["msg" => $msg, "data" => $data]);
            throw new \Exception($msg);
        }
    }


//$appInfoAuthToken = "202410BBf4da048ba29c48809d8f7949931f7C64";
    public function createAppAuthToken(string $code): array
    {
        //单独处理code
        //alipay.open.auth.token.app
        $tokenRequest = new AlipayOpenAuthTokenAppRequest();
        //创建token
        $tokenRequest->setBizContent(json_encode([
            "grant_type" => "authorization_code",
            "code" => $code,
        ], JSON_UNESCAPED_UNICODE));

        $tokenResult = $this->aop->execute($tokenRequest);
        $responseNode = str_replace(".", "_", $tokenRequest->getApiMethodName()) . "_response";
        $response = $tokenResult->$responseNode;
        $resultCode = $response->code;
        if (empty($resultCode) || $resultCode != 10000) {
            throw  new \Exception($response->msg);
        }
        Log::channel("redirect")->info("responseNode：" . date("Y-m-d H:i:s", time()), [
            "data" => json_decode(json_encode($response), true)
        ]);
        //成功
        $providerPid = $response->user_id;
        $providerAPPID = $response->auth_app_id;
        $app_auth_token = $response->app_auth_token;
        $app_refresh_token = $response->app_refresh_token;
        $re_expires_in = $response->re_expires_in + time();
        //更新db

        return [$providerPid, $providerAPPID, $app_auth_token];
    }


    protected function compareSign(array $data): bool
    {
        //签名校验计算
//        $result = $this->aop->rsaCheckV1($data, self::AlipayRasPublicKey, self::SignType);
        $result = $this->aop->rsaCheckV1($data, config("lite.threePartyApplication.alipayrsaPublicKey"), config("lite.threePartyApplication.signType"));

        return $result;
    }

    protected function getSign(array $data): string
    {

        //签名校验计算
//        $strContent = $this->aop->getSignContent($data);
        $strContent = json_encode($data);
//        $sign = $this->aop->alonersaSign($strContent, self::RsaPrivateKKey, self::SignType, false);
        $sign = $this->aop->alonersaSign($strContent, config("lite.threePartyApplication.rsaPrivateKey"), config("lite.threePartyApplication.signType"), false);
        return $sign;
    }

    public function alipayOpenAuthAppauthCancelled(array $requestArray)
    {
        try {
            $result = $this->compareSign($requestArray);
            if (empty($result)) {
                throw new \Exception("签名校验失败");
            }
            $app_id = $requestArray["app_id"];
            if ($app_id != config("lite.threePartyApplication.appId")) {
                throw new \Exception("APPID 无法对应");
            }

            $biz_content = $requestArray["biz_content"];
            if (is_string($biz_content)) {
                $biz_content = json_decode($biz_content, true);
            }
            $pid = $biz_content["user_id"];
            $auth_app_id = $biz_content["auth_app_id"];
            $provider = DeviceServiceProviders::query()->where([
                "pid" => $pid,
                "app_id" => $auth_app_id
            ])->first();
            Log::channel("notify")->info("fromNotifyException：" . date("Y-m-d H:i:s", time()), [
                "result" => $provider,
                "pid" => $pid,
                "app_id" => $auth_app_id
            ]);
            if (!empty($provider)) {
                $provider->is_auth = 0;
                $provider->app_auth_code = "";
                $provider->app_auth_token = "";
                $provider->save();
            }
            return "success";
        } catch (\Exception $e) {
            Log::channel("notify")->info("fromNotifyException：" . date("Y-m-d H:i:s", time()), [
                "msg" => $e->getMessage(),
                "line" => $e->getLine(),
                "file" => $e->getFile()
            ]);
            return "fail";
        }

    }

}